package org.darkforest.common.util;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import org.darkforest.common.logger.Logger;
import org.darkforest.enums.SettingNameEnum;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;

/**
 * Created by valentina on 15/2/5.
 * 阿里云上传工具
 */
public class AliOssFileUploadUtil {

    //上传到云空间的配置参数，已修改为从数据库读取

    public static String accessId;

    public static String bucketName;

    public static String accessKey;

    public static String endPoint;


    /**
     * 上传图片
     * @param albumId
     * @param fileName
     * @param file
     * @throws OSSException
     * @throws ClientException
     * @throws FileNotFoundException
     */
    public static void uploadPic(String albumId,String fileName, File file)
            throws OSSException, ClientException, FileNotFoundException {

//        OSSClient client = getOssClient();
//        ObjectMetadata objectMeta = new ObjectMetadata();
//        objectMeta.setContentLength(file.length());
//        // 可以在metadata中标记文件类型
//        objectMeta.setContentType("image/jpeg");
//
//        InputStream input = new FileInputStream(file);
//        client.putObject(bucketName, fileName, input, objectMeta);
//        Logger.debug(AliOssFileUploadUtil.class,"file:"+fileName+" upload to aliyun success!");
        uploadFile(fileName, file, "goods");
    }

    /**
     * 上传会员二维码到阿里云空间，文件不重命名，如已有同名文件则覆盖
     * @param folder
     * @param file
     */
    public static void uploadQRcode(String folder,File file)
            throws OSSException, ClientException, FileNotFoundException {
//        OSSClient client = getOssClient();
//        ObjectMetadata objectMeta = new ObjectMetadata();
//        objectMeta.setContentLength(file.length());
//        // 可以在metadata中标记文件类型
//        objectMeta.setContentType("image/jpeg");
//
//        InputStream input = new FileInputStream(file);
//        String fileName = folder+"/"+file.getName();
//        client.putObject(bucketName, fileName, input, objectMeta);
//        Logger.debug(AliOssFileUploadUtil.class,"file:"+fileName+" upload to aliyun success!");
        String fileName = folder + "_" + file.getName();
        uploadFile(fileName, file, "goods");
    }


    /***
     *  员工头像、员工照片上传
     *
     * @param fileName
     * @param file
     * @throws Exception
     */
    public static void uploadMemberPic(String memberId, String fileName, File file) throws Exception {
        uploadFile(fileName, file, "member_"+memberId);
    }


    /**
     * 根据相册ID，文件名获取图片的绝对路径
     * @param albumId
     * @param fileName
     * @return
     */
//    public static String getPicPath(String albumId,String fileName){
//        return PATH+albumId+"/"+fileName;
//    }


    /**
     * 生成图片唯一名称用于上传到云空间使用
     * @return
     */
    public static String getPicNewName(){
        Double random = Math.ceil(Math.random() * 100000);
        return DateUtil.unixTimeStamp()+random.intValue();
    }
    /**
     * 获取上传链接
     * @return
     */
    private static OSSClient getOssClient(){
        OSSClient client = new OSSClient(endPoint,accessId, accessKey);
        Logger.debug(AliOssFileUploadUtil.class,"oss client:"+client+","+client.getEndpoint());
        return client;
    }

//    public static void main(String[] args){
//        System.out.print(AliOssFileUploadUtil.getPicNewName());
//    }


    /**
     *  图片上传到图片服务器
     * @param fileName
     * @param file
     */
    public static void uploadFile(String fileName, File file, String imageFlg) throws OSSException {
        try {
            String BOUNDARY = "--------" + UUID.randomUUID().toString(); // 定义数据分隔线
            URL url = new URL(endPoint);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设定请求的方法为"POST"，默认是GET
            conn.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行
            // 设置是否向httpUrlConnection输出，参数要放在http正文内，因此需要设为true, 默认情况下是false;
            conn.setDoOutput(true);
            // 设置是否从httpUrlConnection读入，默认情况下是true;
            conn.setDoInput(true);
            // Post 请求不能使用缓存
            conn.setUseCaches(false);
            // 发出的这个请求建议服务器端保留连接，这样下次你向同一个服务器发请求时可以走同一个连接
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; DigExt)");
            conn.setRequestProperty("Charsert", "UTF-8");
            //conn.setRequestProperty("Content-Length", String.valueOf(info.getBytes().length));
            //conn.setRequestProperty("Content-Length", String.valueOf(file.length()));
            // 设定传送的内容类型是可序列化的java对象(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            // 设置连接主机超时（单位：毫秒）
            conn.setConnectTimeout(60000);
            // 设置从主机读取数据超时（单位：毫秒）
            conn.setReadTimeout(60000);
            // 连接
            // getOutputStream会隐含的进行connect(如同调用conn.connect()方法， 所以在开发中不调用conn.connect()也可以)。
            OutputStream out = new DataOutputStream(conn.getOutputStream());

            // 传输内容
            StringBuilder contentBody = new StringBuilder();
            contentBody .append("--").append(BOUNDARY);

            // 参数上传
            contentBody.append("\r\n");
            contentBody.append("Content-Disposition: form-data; name=\"");
            contentBody.append("imageFlg" + "\"");
            contentBody.append("\r\n");
            contentBody.append("\r\n");
            contentBody.append(imageFlg);
            contentBody.append("\r\n");
            contentBody.append("--").append(BOUNDARY);

            String boundaryMessage1 = contentBody.toString();
            out.write(boundaryMessage1.getBytes("utf-8"));

            // 处理文件上传
            contentBody = new StringBuilder();
            contentBody .append("\r\n");
            contentBody .append("Content-Disposition: form-data;name=\"file" + "\";filename=\"" + fileName + "\"\r\n");
            contentBody .append("Content-Type:application/octet-stream\r\n\r\n");

            String boundaryMessage2 = contentBody.toString();
            out.write(boundaryMessage2.getBytes("utf-8"));

            // 文件读写
            InputStream input = new FileInputStream(file);
            DataInputStream in = new DataInputStream(input);
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();

            out.write("\r\n".getBytes());

            // 写结尾
            String endBoundary = "--" + BOUNDARY + "--\r\n";
            out.write(endBoundary.getBytes("utf-8"));
            out.flush();
            out.close();

            // 调用HttpURLConnection连接对象的getInputStream()函数, 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
            // 定义BufferedReader输入流来读取URL的响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line = null;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
                if (!"上传成功".equals(line)) {
                    Logger.debug(AliOssFileUploadUtil.class,"file:"+fileName+" upload fail!");
                }
            }

            Logger.debug(AliOssFileUploadUtil.class,"file:"+fileName+" upload success!");

        } catch (Exception e) {
            System.out.println("发送POST请求出现异常！" + e);
            e.printStackTrace();
            Logger.debug(AliOssFileUploadUtil.class,"file:"+fileName+" upload fail!");
            Logger.error(AliOssFileUploadUtil.class,e.getLocalizedMessage());
            throw new OSSException();
        }
    }
}
